'use strict';

const Controller = require('egg').Controller;
const SELECT = require('../../../../config/select');
const CONFIG = require('../../../../config/cms.config');
const userAndRole = async (ctx, destory = false) => {
    const body = ctx.request.body;
    const userId = body.userId;
    const roleId = body.roleId;
    const Rules = {
        userId: {
            type: 'objectId',
            keyname: '用户ID'
        },
        roleId: {
            type: 'objectId',
            keyname: '角色ID'
        }
    };
    ctx.proving(Rules);

    await ctx.service.user.userAndRole(userId, roleId, destory);
    ctx.success({
        message: destory ? '角色移除成功' : '角色授予成功'
    })
}

class UserController extends Controller {
    /**
     * 用户查询
     */
    async find() {
        const { ctx } = this;
        const { id, username, state, name, sex, role, phone, weixin, page, currentPage } = ctx.query;
        const select = SELECT.USER;
        const Rules = {
            id: {
                type: 'objectId',
                required: false
            }
        };
        ctx.proving(Rules, ctx.query);
        let roles;
        if (role) {
            roles = role.split(',')
        }
        // 只有超级管理员可以获取所有用户
        if (id) { }
        const user = await ctx.service.user.find({ id, username, state, name, sex, role: roles, phone, weixin, page, currentPage }, select);
        ctx.success(user);
    }

    /**
     * 获取当前登陆者信息
     */
    async userInfo() {
        const { ctx } = this;
        const select = SELECT.USER;

        const user = await ctx.service.user.find({ id: ctx.state.user._id }, select);
        ctx.success(user);
    }

    /**
     * 获取超级管理员信息
     */
    async adminInfo() {
        const { ctx } = this;
        const select = 'username headImg role name';

        const user = await ctx.service.user.find({ username: 'admin' }, select);
        ctx.success(user);
    }

    /**
     * 新增用户, 普通用户 - 非注册接口 - 超级管理员
     */
    async create() {
        const { ctx } = this;
        const body = ctx.request.body;
        const { username, password, state, name, sex, phone, weixin, summary, headImg, email } = body
        const Rules = {
            username: {
                type: 'string',
                required: true,
                allowEmpty: false,
                format: /^[0-9a-zA-Z]+$/,
                min: 4,
                max: 15,
                keyname: '用户名',
            },
            password: {
                type: 'password',
                keyname: '密码'
            }
        };
        ctx.proving(Rules);
        // 角色权限认证
        await ctx.powerValidate();

        const user = await ctx.service.user.create({
            username,
            password,
            name,
            sex,
            phone,
            weixin,
            state,
            summary,
            headImg,
            email
        });
        ctx.success({ id: user.id });
    }

    /**
     * 验证用户名邮箱是否存在
     */
    async provingUser(username, email) {
        const { ctx } = this
        const user = await ctx.model.User.find({
            $or: [{ username }, { email }]
        })

        if (user.length > 0) {
            let msg = ['', '']
            user.map(item => {
                if (item.username === username) {
                    msg[0] = '用户已存在'
                }
                if (item.email === email) {
                    msg[1] = '邮箱已被注册'
                }
            })
            ctx.throw(402, msg.join(' ').trim());
        }
    }
    
    /**
    * 用户注册，邮箱注册
    */
    async register() {
        const { ctx } = this
        const body = ctx.request.body
        const { username, password, email, code } = body

        const Rules = {
            username: {
                type: 'string',
                required: true,
                allowEmpty: false,
                format: /^[0-9a-zA-Z]+$/,
                min: 4,
                max: 15,
                keyname: '用户名',
            },
            password: {
                type: 'password',
                keyname: '密码'
            },
            email: {
                type: 'email',
                keyname: '邮箱'
            },
        };
        ctx.proving(Rules);

        await this.provingUser(username, email);

        // 加密用户信息
        let cipherData = {
            username,
            password,
            email,
            date: Date.now()
        }
        const data = ctx.helper.aesEncode(JSON.stringify(cipherData), CONFIG.emailCipherPassword);

        let url = `http://127.0.0.1:7001/api/v1/emailUrlRegister?data=${data}`

        try {
            const res = await ctx.helper.sendEmail({
                to: email,
                title: 'eggcms邮箱登陆验证',
                html: `<div style="text-align: center;"><h2>请在3小时内点击下面的链接完成注册</h2><a href="${url}">点击这里完成注册</a></div>`
            })
            console.log(res);
            ctx.success({
                message: '我们已经向您的邮箱发送了一封邮件，请在3小时内点击邮件内链接完成注册'
            });
        } catch (e) {
            console.log(e);
            ctx.throw(402, '注册失败');
        }
    }

    /**
     * 邮件链接点击注册
     */
    async emailUrlRegister() {
        const { ctx } = this;
        const data = ctx.query.data
        const Rules = {
            data: {
                type: 'string',
                keyname: 'data'
            }
        };
        ctx.proving(Rules, ctx.query);

        const deData = ctx.helper.aesDecode(data, CONFIG.emailCipherPassword)
        if (ctx.helper.isJson(deData)) {
            const userinfo = JSON.parse(deData);
            // 判断是否超时
            const timer = (Date.now() - userinfo.date) / 3600000;
            console.log(userinfo)
            console.log(timer)
            if (timer >= 3) {
                ctx.throw(402, '注册信息超时，请重新注册认证')
            } else {
                const { username, password, email } = userinfo
                // 验证是否已被注册
                await this.provingUser(username, email);
                // 通过后直接注册此用户并且返回token
                const user = await ctx.service.user.create({
                    username,
                    password,
                    email
                });
                const expiresIn = '100h';
                const token = await ctx.app.jwt.sign({ id: user.id }, ctx.app.config.jwt.secret, { expiresIn });
                ctx.success({ token });
            }
        } else {
            ctx.throw(402, 'data数据非法')
        }
    }

    /**
     * todo
     * 绑定邮箱
     */
    async userBindEmail() {
        const { ctx } = this;
        const body = ctx.request.body;
        const { email } = body;
        const Rules = {
            email: {
                type: 'email',
                keyname: '邮箱'
            },
        };
        ctx.proving(Rules);
        const user = await ctx.model.User.find({ email })
        if (user.length > 0) {
            ctx.throw(402, '邮箱已被绑定')
            return
        }
    }


    /*
    * 修改用户信息
    * */
    async update() {
        const { ctx } = this;
        const body = ctx.request.body;
        const { name, sex, phone, id, summary, weixin, headImg, state } = body;
        
        const Rules = {
            id: {
                type: 'objectId',
                keyname: 'ID'
            },
            headImg: {
                type: 'string',
                keyname: '用户头像'
            }
        };
        ctx.proving(Rules);
        // 角色权限认证
        await ctx.powerValidate(id);
        console.log(ctx.state);
        const user = await ctx.service.user.update(id, { name, state, sex, phone, id, summary, weixin, headImg });

        ctx.success({
            message: '修改成功',
            id: user.id,
            updateAt: this.app.dateFormat(user.updateAt)
        });
    }

    /*
    * 重置用户密码
    * */
    async restPassword() {
        const { ctx } = this;
        const id = ctx.request.body.id;
        const password = ctx.request.body.password || '123456';

        const Rules = {
            id: {
                type: 'objectId',
                keyname: 'ID'
            },
        };

        ctx.proving(Rules);
        // 角色权限认证
        await ctx.powerValidate();

        const user = await ctx.service.user.update(id, { password });
        ctx.success({
            message: '重置密码成功',
            updateAt: this.app.dateFormat(user.updateAt)
        });
    }

    /*
    * 封禁/解封用户
    * */
    async userStatus() {
        const { ctx } = this;
        const body = ctx.request.body;
        const { id, state } = body;
        if (!['1', '2'].includes(state)) {
            ctx.throw(402, '状态信息传入不正确');
        }
        const Rules = {
            id: {
                type: 'objectId',
                keyname: 'ID'
            },
        };

        ctx.proving(Rules);
        // 角色权限认证
        await ctx.powerValidate();

        const user = await ctx.service.user.update(id, { state });
        ctx.success({
            message: '状态变更成功',
            updateAt: this.app.dateFormat(user.updateAt)
        });
    }

    /*
    * 删除用户
    * */
    async destroy() {
        const { ctx } = this;
        const id = ctx.request.body.id;

        const Rules = {
            id: {
                type: 'objectId',
                keyname: 'ID'
            }
        };

        ctx.proving(Rules);
        // 角色权限认证
        await ctx.powerValidate();

        const user = await ctx.service.user.update(id, { state: 0 });
        ctx.success({
            message: '删除成功',
            updateAt: this.app.dateFormat(user.updateAt)
        });
    }

    /*
    * 为用户添加角色
    * */
    async addRole(destory = false) {
        const { ctx } = this;
        // 角色权限认证
        await ctx.powerValidate();
        await userAndRole(ctx);
    }

    /*
    * 为用户移除角色
    * */
    async destroyRole() {
        const { ctx } = this;
        // 角色权限认证
        await ctx.powerValidate();
        await userAndRole(ctx, true);
    }
}

module.exports = UserController;
